/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.dejax.service.impl;


import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import com.dejax.domain.BaseSysAppinfo;
import com.dejax.exception.BadRequestException;
import com.dejax.utils.ValidationUtil;
import com.dejax.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.dejax.repository.BaseSysAppinfoRepository;
import com.dejax.service.BaseSysAppinfoService;
import com.dejax.service.dto.BaseSysAppinfoDto;
import com.dejax.service.dto.BaseSysAppinfoQueryCriteria;
import com.dejax.service.mapstruct.BaseSysAppinfoMapper;
import org.apache.poi.ss.formula.functions.T;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.dejax.utils.PageUtil;
import com.dejax.utils.QueryHelp;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import java.util.function.Function;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author Richer
* @date 2021-12-23
**/
@Service
@RequiredArgsConstructor
public class BaseSysAppinfoServiceImpl implements BaseSysAppinfoService {

    private final BaseSysAppinfoRepository baseSysAppinfoRepository;
    private final BaseSysAppinfoMapper baseSysAppinfoMapper;
    @PersistenceContext
    private EntityManager entityManager;


    @Override
    public Map<String,Object> queryAll(BaseSysAppinfoQueryCriteria criteria, Pageable pageable){
        Page<BaseSysAppinfo> page = baseSysAppinfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(baseSysAppinfoMapper::toDto));
    }

    @Override
    public Map<String,Object> queryMyAllData(BaseSysAppinfoQueryCriteria criteria, Pageable pageable){
        System.out.println(criteria);
        Page<BaseSysAppinfo> page = baseSysAppinfoRepository.queryMyAllData(criteria,pageable);

        return PageUtil.toPage(page);
    }



    @Override
    public Page<BaseSysAppinfo>  queryAllData(BaseSysAppinfoQueryCriteria criteria, Pageable pageable){
        StringBuffer dataBuffer = new StringBuffer(
                "SELECT appinfo.*,projinfo.projname FROM base_sys_appinfo appinfo " +
                        "left join base_sys_projinfo projinfo on  appinfo.projid =projinfo.projid" +
                        " WHERE 1 = 1");
        StringBuffer countBuffer = new StringBuffer(
                "select count(*) FROM base_sys_appinfo appinfo " +
                        "left join base_sys_projinfo projinfo on  appinfo.projid =projinfo.projid " +
                        "WHERE 1 = 1");

        StringBuffer paramBuffer = new StringBuffer();

        //系统名称
        if(criteria.getAppname() != null){
            paramBuffer.append(" AND appinfo.appname like '%" + criteria.getAppname() + "%'");
        }

        //所属商业项目
        if(criteria.getProjid() != null){
            //传来的是projname 不是projid
            paramBuffer.append(" AND projinfo.projname like '%" + criteria.getProjid() + "%'");
        }

        paramBuffer.append(" AND appinfo.flag = 0");

        StringBuffer orderBuffer = new StringBuffer(
                "");

        String dataSql = (dataBuffer.append(paramBuffer).append(orderBuffer))
                .toString();
        String countSql = (countBuffer.append(paramBuffer)).toString();

        System.out.println("{} dataSql= " + dataSql);
        System.out.println("{} countSql= " + countSql);

        Query dataQuery = entityManager.createNativeQuery(dataSql.toString());
        Query countQuery = entityManager.createNativeQuery(countSql.toString());

        dataQuery.setFirstResult((int) pageable.getOffset());
        dataQuery.setMaxResults(pageable.getPageSize());
        dataQuery.unwrap(NativeQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        BigDecimal count = BigDecimal.valueOf(Integer.valueOf(String.valueOf(countQuery.getSingleResult())));
        Integer total = count.intValue();

        List content = total > pageable.getOffset() ? dataQuery
                .getResultList() : Collections.emptyList();


        return new PageImpl<BaseSysAppinfo>(content,pageable,total);

    }

    @Override
    public List<BaseSysAppinfoDto> queryAll(BaseSysAppinfoQueryCriteria criteria){
        return baseSysAppinfoMapper.toDto(baseSysAppinfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public BaseSysAppinfoDto findById(String appid) {
        BaseSysAppinfo baseSysAppinfo = baseSysAppinfoRepository.findById(appid).orElseGet(BaseSysAppinfo::new);
        ValidationUtil.isNull(baseSysAppinfo.getAppid(),"BaseSysAppinfo","appid",appid);
        return baseSysAppinfoMapper.toDto(baseSysAppinfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseSysAppinfoDto create(BaseSysAppinfo resources) {
        resources.setAppid(IdUtil.simpleUUID());
        resources.setFlag(0);
        //查重
        BaseSysAppinfo baseSysAppinfo = baseSysAppinfoRepository.findOneByAppnameSyscodeProjid(resources.getAppname(),resources.getSyscode(),resources.getProjid());
        if(baseSysAppinfo != null){
            throw new BadRequestException(BAD_REQUEST, "该系统名称已存在");
        }
        return baseSysAppinfoMapper.toDto(baseSysAppinfoRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(BaseSysAppinfo resources) {
        BaseSysAppinfo baseSysAppinfo = baseSysAppinfoRepository.findById(resources.getAppid()).orElseGet(BaseSysAppinfo::new);
        ValidationUtil.isNull( baseSysAppinfo.getAppid(),"BaseSysAppinfo","id",resources.getAppid());
        baseSysAppinfo.copy(resources);
        baseSysAppinfoRepository.save(baseSysAppinfo);
    }

    @Override
    public void deleteAll(String[] ids) {
        BaseSysAppinfo updateSource = new BaseSysAppinfo();
        for (String appid : ids) {
            //改为 update
            updateSource.setAppid(appid);
            updateSource.setFlag(1);
            this.update(updateSource);
        }
    }

    @Override
    public void download(List<BaseSysAppinfoDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (BaseSysAppinfoDto baseSysAppinfo : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("系统名称", baseSysAppinfo.getAppname());
            map.put("系统描述", baseSysAppinfo.getAppdesc());
            map.put("所属商业项目", baseSysAppinfo.getProjid());
            map.put("系统代码", baseSysAppinfo.getSyscode());
            map.put("系统key", baseSysAppinfo.getAppkey());
            map.put("系统密钥", baseSysAppinfo.getAppscrect());
            map.put("系统类型", baseSysAppinfo.getApptype());
            map.put(" flag",  baseSysAppinfo.getFlag());
            map.put(" notes",  baseSysAppinfo.getNotes());
            map.put(" reguser",  baseSysAppinfo.getReguser());
            map.put(" regtime",  baseSysAppinfo.getRegtime());
            map.put(" moduser",  baseSysAppinfo.getModuser());
            map.put(" modtime",  baseSysAppinfo.getModtime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}